package com.lcj.hub.common.aspect;

import com.lcj.hub.common.exception.DuplicateSubmissionException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@Aspect
public class RepeatSubmitAspect {

    private final RedisTemplate<String, Object> redisTemplate;

    public RepeatSubmitAspect(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }


    @Around("@annotation(repeatSubmit)")
    public Object around(ProceedingJoinPoint joinPoint, RepeatSubmit repeatSubmit) throws Throwable {
        String redisKey = getString();
        log.info("========== redisKey ========== {}", redisKey);

        if (Boolean.FALSE.equals(redisTemplate.hasKey(redisKey))) {
            redisTemplate.opsForValue().set(redisKey, redisKey, repeatSubmit.expireTime(), TimeUnit.SECONDS);
            try {
                //正常执行方法并返回
                return joinPoint.proceed();
            } catch (Throwable throwable) {
                redisTemplate.delete(redisKey);
                throw new Throwable(throwable);
            }
        } else {
            // 抛出异常
            throw new DuplicateSubmissionException("请勿重复提交");
        }
    }

    private static String getString() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        assert attributes != null;
        HttpServletRequest request = attributes.getRequest();
        // TODO 获取token当做key
//         String token = request.getHeader("Authorization");
        String token = "token";
        String url = request.getRequestURI();
        return "repeat_submit_key:"
                .concat(url)
                .concat(token);
    }
}